var YHZIndexCounter = 201;

function YHItem(){
	var Title = "";
	this.setTitle = function(newTitle) {
		Title = newTitle;
		return this;
	};
	this.getTitle = function() {
		return Title;
	};
	var top = 0;
	this.setTop = function(num){
		top = num;
		if(divItem)
			divItem.css('top', num+'px');
		return this;
	};
	this.getTop = function(){
		return (divItem) ? divItem.position().top : top;
	};
	var left = 0;
	this.setLeft = function(num){
		left = num;
		if(divItem)
			divItem.css('left', num+'px');
		return this;
	};
	this.getLeft = function(){
		return (divItem) ? divItem.position().left : left;
	};
	var width = YHConstants.item.width;
	var WidthHalf = width / 2;
	this.setWidth = function(num){
		width = num;
		if(divItem)
			divItem.css('width', num+'px');
		WidthHalf = num / 2;
		return this;
	};
	this.getWidth = function(){
		return (divItem) ? divItem.width() : width;
	};
	this.getWidthHalf = function(){
		if(!WidthHalf)
			WidthHalf = this.getWidth() / 2;
		return WidthHalf;
	};
	var height = YHConstants.item.height;
	var HeightHalf;
	this.setHeight = function(num){
		if(!divItem)
			height = num;
		else
			divItem.css('height', num+'px');
		HeightHalf = num / 2;
		return this;
	};
	this.getHeight = function(){
		return (divItem) ? divItem.height() : height;
	};
	this.getHeightHalf = function(){
		if(!HeightHalf)
			HeightHalf = this.getHeight() / 2;
		return HeightHalf;
	};
	var Z_Index = 0;
	this.getZIndex = function(){
		return (!divItem) ? Z_Index : divItem.css('z-index');
	};
	this.setZIndex = function(zindex){
		Z_Index = zindex;
		if(divItem)
			divItem.css('z-index', Z_Index);
		return this;
	};
	
	this.getBottom = function(y){
		return ((y) ? y : this.getTop()) + this.getHeight();
	};
	
	this.getRight = function(x){
		return ((x) ? x : this.getLeft()) + this.getWidth();
	};
	
	var Thickness = YHConstants.item.thickness;
	var ThicknessHalf = null;
	
	this.getThickness = function() {
		return Thickness;
	};
	this.getThicknessHalf = function(){
		return ThicknessHalf;
	}
	this.setThickness = function(val){
		Thickness = val;
		ThicknessHalf = val / 2;
		return this;
	};
	this.isInRect = function(x, y) {
		return this.isVisible() && (x >= this.getLeft()) && (x <= this.getRight()) && (y >= this.getTop()) && (y <= this.getBottom());
	};
	this.isInside = function(x, y) {
		var isAfter = this.isInRect(x, y);
		if(isAfter)
		{
			if(!Thickness)
			{
				return isAfter;
			}
			else
			{
				var bottom = this.getBottom();
				if((y + YHConstants.item.space) < bottom)
					YumeHikkiEngine.Player.goBack(this);
				return (y >= bottom - Thickness) && (y <= bottom);
			}
		}
		else
		{
			YumeHikkiEngine.Player.goFront(this);
			return false;
		}
	};
	var divItem = null;
	this.getDivItem = function(){
		return divItem;
	};
	this.cssClass = "";
	var Image = "";
	this.setImage = function (url){
		if(url){
			Image = url;
			if(divItem)
				divItem.css("background-image", "url(pic/" + Image + ")");
		}
		return this;
	};
	this.getImage = function(){
		return Image;
	};
	this.Draw = function() {
		var divElem=document.createElement('div');
		divItem = $(divElem);
		divItem.addClass(this.cssClass);
		divItem.css('width', width + "px");
		divItem.css('height', height + "px");
		divItem.css('top', top + "px");
		divItem.css('left', left + "px");
		if(Image)
			this.setImage(Image);
		if(Z_Index)
			divItem.css('z-index', Z_Index);
		divItem.appendTo(YumeHikkiEngine.getWrapper());
	};
	this.isTransparent = function(){
		return true; 
	};
	this.isDiagonal = function(){
		return false; 
	};
	this.isLiving = function(){
		return false;
	};
	this.getCenter = function(){
		return new YHPoint(this.getLeft() + this.getWidthHalf(), this.getTop() + this.getHeightHalf());
	};
	this.Show = function(){
		if(divItem)
			divItem.show();
		return this;
	};
	this.Hide = function(){
		if(divItem)
			divItem.hide();
		return this;
	};
	
	this.isVisible = function() {
		return (divItem && divItem.is(':visible'));
	}
	this.setZIndex(YHZIndexCounter);
	YHZIndexCounter++;
	this.Action = null;
	var AutoAction = false;
	this.AutoActionOn = function(){
		AutoAction = true;
		return this;
	};
	this.AutoActionOff = function(){
		AutoAction = false;
		return this;
	};
	this.isAutoAction = function(){
		return AutoAction && (typeof(this.Action) == "function");
	};
	this.getAutoAction = function(){
		return val;
	};
	this.setAutoAction = function(val){
		AutoAction = val;
		return this;
	};
	YumeHikkiEngine.ItemsInRoom.push(this);
}

function YHItemTransparent(){
	this.Inherits(YHItem);
}

function YHItemNonTransparent(){
	this.Inherits(YHItem);
	this.isTransparent = function(){
		return false; 
	};
}

function YHDoor(place){
	this.Inherits(YHItemNonTransparent);
	this.Places = new Array();
	this.getPlace = function(){
		var len = this.Places.length;
		if(!len)
			return "";
		if(len == 1)
			return this.Places[0];
		return this.Places[getRandom(len)].getScene();
	}
	
	this.Action = function(){
		var place = this.getPlace();
		if(place.isItemTitle())
			YumeHikkiEngine.TeleportTo(place.getScene(), place.getTitle());
		else if(place.isItemCoord())
			YumeHikkiEngine.NavigateTo(place.getScene(), place.getX(), place.getY());
		else
			YumeHikkiEngine.TeleportTo(place.getScene(), this.getTitle());
	};
	this.setPlace = function(plc, x, y) {
		if(plc){
			this.Places.length = 0;
			this.addPlace(plc, x, y);
		}
		return this;
	};
	this.addPlace = function(plc, x, y){
		if(plc)
			this.Places.push(new YHLinkToScene(plc, x, y));
		return this;
	};
	this.isRandom = function() {
		return places.length > 0;
	};
	this.addPlace(place);
	this.AutoActionOn();
}

function YHCharacter(){
	this.Inherits(YHItemNonTransparent);
	this.isLiving = function(){
		return true;
	};
	this.getActivePoint = function(){
		return new YHPoint(this.getLeft() + this.getWidthHalf(), this.getBottom());
	};
	this.getActivePointFor = function(x, y){
		return new YHPoint(x + this.getWidthHalf(), y + this.getHeight());
	};
	var HidingObject = null;
	this.goBack = function(obj){
		this.setZIndex(obj.getZIndex() - YHConstants.zindex_step);
		HidingObject = obj;
		return this;
	};
	this.goFront = function(obj){
		if(HidingObject == obj)
			this.goFrontForce();
		return this;
	};
	this.goFrontForce = function(){
		this.setZIndex(YHConstants.scene.player.zindex);
		HidingObject = null;
		return this;
	};
	var Speed = YumeHikkiEngine.getSpeed();	
	this.getSpeed = function(){
		return Speed;
	};
	this.setSpeed = function(newSpeed){
		Speed = newSpeed;
		return this;
	};
	this.setZIndex(YHConstants.scene.player.zindex);
}

function YHPlayer(){
	this.Inherits(YHCharacter);
	this.cssClass += " YHPlayer";
	this.Direction = null;
	this.AnimationItem = 0;
	this.moveX = function(x, dir) {
		this.ClearDestination();
		this.Direction = dir;
		this.getDivItem().addClass(dir);
		this.getDivItem().delay(100).css('backgroundPosition', -this.getWidth() * this.AnimationItem + "px 0px");
		this.AnimationItem += 1;
		if(this.AnimationItem >= 3)
			this.AnimationItem = 0;
		if(YumeHikkiEngine.CanMove(this, x, this.getTop())){
			this.getDivItem().css('left', x);
		}
	};
	this.moveY = function(y, dir) {
		this.ClearDestination();
		this.Direction = dir;
		this.getDivItem().delay(100).css('backgroundPosition', -this.getWidth() * this.AnimationItem + "px 0px");
		this.AnimationItem += 2;
		if(this.AnimationItem >= 3)
			this.AnimationItem = 0;
		this.getDivItem().addClass(dir);
		if(YumeHikkiEngine.CanMove(this, this.getLeft(), y)){
			this.getDivItem().css('top', y);
		}
	};
	
	this.Destionations = ['left', 'right', 'up', 'down'];
	this.ClearDestination = function(){
		var DestionationsLength = this.Destionations.length;
		var i = 0;
		while(i < DestionationsLength) {
			this.getDivItem().removeClass(this.Destionations[i]);
			i++;
		}
	};
	this.Stop = function(){
		this.getDivItem().css('backgroundPosition', -this.getWidth() + "px 0px");
	};
	
	this.setWidth(YHConstants.scene.player.width);
	this.setHeight(YHConstants.scene.player.height);
}

function YHPerson(){
	this.Inherits(YHCharacter);
}

function YHEnemy(){
	this.Inherits(YHPerson);
}

function YHFurniture(img){
	this.Inherits(YHItemNonTransparent);
	this.cssClass += " YHFurniture";
	if(img)
		this.setImage(img);
}

function YHWall(img){
	this.Inherits(YHFurniture);
	this.cssClass += " YHWall";
	if(img)
		this.setImage(img);

	var Diagonal = null;
	this.IsDiagonal = function() {
		return Diagonal != null;
	};
	this.getDiagonal = function() {
		return Diagonal;
	};
	this.setDiagonal = function(newDiagonal) {
		Diagonal = newDiagonal;
		return this;
	};
	var WallHeight = null;
	var WallHeightCoeff = YHConstants.wall.heightcoeff;
	this.setWallHeight = function(newHeight){
		var h = this.getHeight();
		if(newHeight < h){
			WallHeight = newHeight;
			WallHeightCoeff = newHeight / this.getHeight();
		}
		return this;
	};
	this.getWallHeight = function(){
		return WallHeight;
	}
	this.getWallHeightCoeff = function(){
		return WallHeightCoeff;
	};
	this.WallLine = null;
	this.getWallLine = function() {
		return this.WallLine;
	}
	this.setWallThickness = function(val){
		this.setThickness(val);
		var halfT = this.getThicknessHalf();
		var top = this.getTop();
		var left = this.getLeft();
		var w = this.getWidth();
		var h = this.getHeight();
		var Ax = left + halfT;
		var Ay = top + this.getWallHeightCoeff() * h;
		var Bx = left + w - halfT;
		var By = top + h;
		if(Diagonal == YHConstants.diagonal.left_to_right) {
			this.WallLine = new YHLine(new YHPoint(Ax, Ay), new YHPoint(Bx, By));
		}
		else {
			this.WallLine = new YHLine(new YHPoint(Ax, By), new YHPoint(Bx, Ay));
		}
		return this;
	};
	this.getWallThickness = function(){
		return this.getThickness();
	}
	var HorizontalBorder = null;
	var VerticalBorder = null;
	this.setPoints = function(Ax, Ay, Bx, By) {
		HorizontalBorder = null;
		VerticalBorder = null;
		this.WallLine = null;
		if((Ax == Bx) && (Ax == By)){
			Diagonal = YHConstants.diagonal.none;
		}
		else if(Ax == Bx) {
			Diagonal = YHConstants.diagonal.vertical;
			VerticalBorder = Ax;
			this.setTop(Math.min(Ay, By));
			this.setLeft(Ax);
			this.setWidth(this.getThickness());
			this.setHeight(Math.abs(Ay - By));
			ParamA = 0;
			ParamB = 0;
		}
		else if(Ay == By) {
			Diagonal = YHConstants.diagonal.horizontal;
			HorizontalBorder = Ay;
			this.setTop(Ay);
			this.setLeft(Math.min(Ax, Bx));
			this.setWidth(Math.abs(Ax - Bx));
			this.setHeight(this.getThickness());
			ParamA = Ay;
		}
		else {
			this.WallLine = new YHLine(new YHPoint(Ax, Ay), new YHPoint(Bx, By));
			if((Ax < Bx) && (Ay < By))
				Diagonal = YHConstants.diagonal.left_to_right;
			else
				Diagonal = YHConstants.diagonal.right_to_left;
		}
	};
	this.isCrossing = function(x, y) {
		if(!this.isInRect(x, y))
			return false;
		if(!this.WallLine)
			return false;
		if(Diagonal == YHConstants.diagonal.none)
			return false;
		if (Diagonal == YHConstants.diagonal.left_to_right || Diagonal == YHConstants.diagonal.right_to_left)
		{
			var posTo = this.WallLine.LengthTo(x, y);
			if(posTo == null)
				return false;
			return Math.abs(posTo) <= this.getThicknessHalf();
		}
		else if(Diagonal == YHConstants.diagonal.vertical) {
			return Math.abs(x - VerticalBorder) <= this.getThickness();
		}
		else if(Diagonal == YHConstants.diagonal.horizontal) {
			return Math.abs(y - HorizontalBorder) <= this.getThickness();
		}
		else {
			return false;
		}
	};
	this.CheckVisibility = function(x, y){
		if(this.WallLine == null)
			return this;
		var posTo = this.WallLine.LengthTo(x, y);
		if(posTo == null)
			return this;
		if(posTo > YHConstants.wall.space)
			YumeHikkiEngine.Player.goBack(this);
		else if(posTo < -YHConstants.wall.space)
			YumeHikkiEngine.Player.goFront(this);
		return this;
	};
	this.getWallRegion = function(x){
		var wallRegion = YHConstants.wallregion.none;
		if(x <= this.getLeft() + this.getWallThickness())
			wallRegion = YHConstants.wallregion.close;
		else if(x >= this.getRight() + this.getWallThickness())
			wallRegion = YHConstants.wallregion.far;
		else
			wallRegion = YHConstants.wallregion.middle;
		if(this.getDiagonal() == YHConstants.diagonal.right_to_left)
			wallRegion = YHConstants.wallregion.max - wallRegion;
		return wallRegion;
	};
}

function YHStair(){
	this.Inherits(YHItemNonTransparent);
}

YumeHikkiEngine.ItemsInRoom.length = 0;
YumeHikkiEngine.Scene = null;